#include "Unite.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>

void InitialisationUnite (Unite * u,const int type ,const int equipe)
{
	(*u).equipe = equipe;
	(*u).type = type;
	(*u).utilise = 1;
	switch(type) 
	{
/* Bucheron */		
		case 1:
			(*u).vie = 100;
			(*u).attaque = 0;
			(*u).defense = 0;	
			(*u).deplacement = 4;
			(*u).utilise = 1;
		break;	
	
/* Pêcheur */
		case 2:
			(*u).vie = 100;
			(*u).attaque = 0;
			(*u).defense = 0;
			(*u).deplacement = 4;
			(*u).equipe = equipe;
			(*u).utilise = 1;
		break;

/* Infanterie 1 */
		case 3:
			(*u).vie = 100;
			(*u).attaque = 0.3;
			(*u).defense = 0.1;
			(*u).deplacement = 4;
			(*u).equipe = equipe;
			(*u).utilise = 1;
		break;

/* Infanterie 2 */
		case 4:
			(*u).vie = 100;
			(*u).attaque = 0.5;
			(*u).defense = 0.2;
			(*u).deplacement = 3;
			(*u).equipe = equipe;
			(*u).utilise = 1;
		break;
		
/* Infanterie 3 */
		case 5:
			(*u).vie = 100;
			(*u).attaque = 0.8;
			(*u).defense = 0.4;
			(*u).deplacement = 3;
			(*u).equipe = equipe;
			(*u).utilise = 1;
		break;
		
		default : 
			(*u).vie = 0;
			(*u).attaque = 0;
			(*u).defense = 0;
			(*u).deplacement = 0;
			(*u).equipe = equipe;
			(*u).utilise = 1;	
		break;
	}
}

void DestructionUnite(Unite * u)
{
	(*u).type = 0;
	(*u).vie = 0;
	(*u).attaque = 0;
	(*u).defense = 0;
	(*u).deplacement = 0;
	(*u).equipe = 0;
	(*u).utilise = 0;
}

void ModifierUtiliseUnite (Unite * u, int utilise)
{
assert(utilise ==0 || utilise == 1);
	(*u).utilise = utilise;
}

int CombatUnite (Unite * u1, Unite * u2)
{
	int ajout = 0;
	int attaque1 ;
	int attaque2 = (*u2).vie * (*u2).attaque - (*u1).vie * (*u1).defense;
	srand(time(NULL));
	ajout = (rand() % 15); /* Bonus d'attaque pour le premier attaquant */
	attaque1 = (*u1).vie * (*u1).attaque + ajout - (*u2).vie * (*u2).defense;
	
	if (attaque1 < 1)
	{
		attaque1 = 1;
	}
	if (attaque2 < 1)
	{
		if( (*u2).type == 1 || (*u2).type == 2)
		{
			attaque2 = 0;
		}
		else
		{
			attaque2 = 1;	
		}
	}
	
	(*u2).vie = (*u2).vie - attaque1;
	if ((*u2).vie <= 0)
	{
		return 1;
	}
	(*u1).vie = (*u1).vie - attaque2;
	if ((*u1).vie <= 0)
	{
		return 2;
	}
	return 0;
}

void UniteTestRegression()
{
	Unite *utest = (Unite*)malloc(sizeof(Unite));
	Unite *utest2 = (Unite*)malloc(sizeof(Unite));
	int testresult;

	/* Vérification de la procédure InitialisationUnite */
	/* Vérification si l'unite est de type bûcheron et d'équipe 0 */
	InitialisationUnite(utest, 1, 0);
	assert( (*utest).type == 1);
	assert( (*utest).equipe == 0);
	assert( (*utest).vie == 100);
	assert( (*utest).attaque == 0);
	assert( (*utest).defense == 0);
	assert( (*utest).deplacement == 4);
	assert( (*utest).utilise == 1);

	/* Vérification si l'unite est de type pêcheur */
	InitialisationUnite(utest, 2, 0);
	assert( (*utest).type == 2);
	assert( (*utest).equipe == 0);
	assert( (*utest).vie == 100);
	assert( (*utest).attaque == 0);
	assert( (*utest).defense == 0);
	assert( (*utest).deplacement == 4);
	assert( (*utest).utilise == 1);
	
	/* Vérification si l'unité est de type infanterie1 */
	InitialisationUnite(utest, 3, 0);
	assert( (*utest).type == 3);
	assert( (*utest).equipe == 0);
	assert( (*utest).vie == 100);
	assert( (*utest).attaque == (float)0.3);
	assert( (*utest).defense == (float)0.1);
	assert( (*utest).deplacement == 4);
	assert( (*utest).utilise == 1);
	
	/* Vérification si l'unité est de type Infanterie2 */
	InitialisationUnite(utest, 4, 0);
	assert( (*utest).type == 4);
	assert( (*utest).equipe == 0);
	assert( (*utest).vie == 100);
	assert( (*utest).attaque == (float)0.5);
	assert( (*utest).defense == (float)0.2);
	assert( (*utest).deplacement == 3);
	assert( (*utest).utilise == 1);
	
	/* Vérification si l'unité est de type Infanterie3 */
	InitialisationUnite(utest, 5, 0);
	assert( (*utest).type == 5);
	assert( (*utest).equipe == 0);
	assert( (*utest).vie == 100);
	assert( (*utest).attaque == (float)0.8);
	assert( (*utest).defense == (float)0.4);
	assert( (*utest).deplacement == 3);
	assert( (*utest).utilise == 1);
	
	/* Vérification de la procédure ModifierUtiliseUnite */
	ModifierUtiliseUnite(utest, 1);
	assert( (*utest).utilise == 1);

	/* Vérification de la procédure CombatUnite */
	/* Test avec (attaque1 < 1) et ((*utest).vie>0)  */
	
	InitialisationUnite(utest, 3, 0);
	InitialisationUnite(utest2, 5, 1);
	testresult = CombatUnite(utest, utest2);
	assert( (*utest2).vie == 99);
	assert( testresult == 0);
	
	/* Test passant dans la boucle if (attaque2 < 1) et ((*utest2).vie>0 */
	
	InitialisationUnite(utest, 5, 0);
	InitialisationUnite(utest2, 3, 1);
	testresult = CombatUnite(utest, utest2);
	assert( (*utest).vie == 99);
	assert( testresult == 0);
	
	/* Test passant dans la boucle if ((*utest2).vie < 0) */
	
	InitialisationUnite(utest, 5, 0);
	InitialisationUnite(utest2, 3, 1);
	(*utest2).vie -= 50;
	testresult = CombatUnite(utest, utest2);
	assert( (*utest2).vie <= 0);
	assert( testresult == 1);
	
	/* Test passant dans la boucle if ((*utest2).vie < 0) */
	
	InitialisationUnite(utest, 3, 0);
	InitialisationUnite(utest2, 5, 1);
	(*utest).vie -= 50;
	testresult = CombatUnite(utest, utest2);
	assert( (*utest).vie <= 0);
	assert( testresult == 2);

		/* Vérification de la procédure DestructionUnite */
	DestructionUnite(utest);
	assert( (*utest).type == 0);	
	assert( (*utest).equipe == 0);
	assert( (*utest).vie == 0);
	assert( (*utest).attaque == 0);
	assert( (*utest).defense == 0);
	assert( (*utest).deplacement == 0);
	assert( (*utest).utilise == 0);
	DestructionUnite(utest2);
	
	free(utest);
	free(utest2);
}
